package com.clarence.dada.modular.system.app.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.clarence.dada.core.base.PageResult;
import com.clarence.dada.core.enums.ErrorEnum;
import com.clarence.dada.core.enums.StatusEnum;
import com.clarence.dada.core.enums.YesOrNotEnum;
import com.clarence.dada.core.exception.BusException;
import com.clarence.dada.core.exception.ServiceException;
import com.clarence.dada.core.factory.PageFactory;
import com.clarence.dada.core.factory.PageResultFactory;
import com.clarence.dada.modular.system.app.entity.SysAppEntity;
import com.clarence.dada.modular.system.app.entity.dto.SysAppDto;
import com.clarence.dada.modular.system.app.entity.req.SysAppReq;
import com.clarence.dada.modular.system.app.entity.resp.SysAppResp;
import com.clarence.dada.modular.system.app.mapper.SysAppMapper;
import com.clarence.dada.modular.system.app.service.SysAppService;
import com.clarence.dada.modular.system.menu.service.SysMenuService;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 系统应用service接口实现类
 *
 * @author GD
 * @since 2020/3/13 16:15
 */
@Service
public class SysAppServiceImpl extends ServiceImpl<SysAppMapper, SysAppEntity> implements SysAppService {

    @Lazy
    @Resource
    private SysMenuService sysMenuService;

    @Override
    public void appAdd(SysAppReq req) {
        SysAppEntity sysAppEntity = Convert.convert(SysAppEntity.class, req);
        if (ObjectUtil.isEmpty(sysAppEntity.getAppSort())) {
            // 默认排序值
            sysAppEntity.setAppSort(999);
        }
        sysAppEntity.setTopFlag(YesOrNotEnum.N.getCode());
        sysAppEntity.setStatusFlag(StatusEnum.ENABLE.getCode());
        this.save(sysAppEntity);
    }

    @Override
    public void appDelete(SysAppReq sysAppReq) {
        SysAppEntity sysAppEntity = this.getBaseMapper().selectById(sysAppReq.getAppId());
        // 该应用下有菜单，则不能删除
        if (sysMenuService.hasMenu(sysAppEntity.getAppCode())) {
            throw new BusException(ErrorEnum.APP_CANNOT_DELETE);
        }
        // 逻辑删除
        sysAppEntity.setDelFlag(YesOrNotEnum.Y.getCode());
        this.updateById(sysAppEntity);
    }

    @Override
    public void appEdit(SysAppReq req) {
        SysAppEntity sysAppEntity = this.getBaseMapper().selectById(req.getAppId());
        BeanUtil.copyProperties(req, sysAppEntity);

        // 不能修改编码
        sysAppEntity.setAppCode(null);
        // 不能修改状态，修改状态接口修改状态
        sysAppEntity.setStatusFlag(null);
        // 不能修改激活，激活接口激活应用
        sysAppEntity.setTopFlag(null);
        this.updateById(sysAppEntity);
    }

    @Override
    public void appUpdateStatus(SysAppReq req) {
        if (ObjectUtil.isEmpty(req.getAppId())) {
            throw new BusException(ErrorEnum.ERROR_NULL_PARAMS);
        }
        SysAppEntity currentApp = this.getBaseMapper().selectById(req.getAppId());
        if (ObjectUtil.isEmpty(currentApp)) {
            throw new ServiceException(ErrorEnum.APP_NOT_EXIST);
        }
        currentApp.setStatusFlag(req.getStatusFlag());
        this.updateById(currentApp);
    }

    @Override
    public SysAppResp appDetail(SysAppReq req) {
        if (ObjectUtil.isEmpty(req.getAppId())) {
            throw new BusException(ErrorEnum.ERROR_NULL_PARAMS);
        }
        SysAppEntity sysAppEntity = getBaseMapper().selectById(req.getAppId());
        if (ObjectUtil.isEmpty(sysAppEntity)) {
            return null;
        }
        return Convert.convert(SysAppResp.class, sysAppEntity);
    }

    @Override
    public List<SysAppResp> appDropDown(SysAppReq req) {
        req.setStatusFlag(StatusEnum.ENABLE.getCode());
        LambdaQueryWrapper<SysAppEntity> wrapper = createWrapper(req);
        List<SysAppEntity> sysAppList = this.list(wrapper);
        return Convert.convert(new TypeReference<>() {
        }, sysAppList);
    }

    @Override
    public PageResult<SysAppResp> appPage(SysAppReq req) {
        LambdaQueryWrapper<SysAppEntity> wrapper = createWrapper(req);
        Page<SysAppEntity> page = this.page(PageFactory.defaultPage(), wrapper);
        List<SysAppResp> respList = Convert.convert(new TypeReference<>() {}, page.getRecords());
        return PageResultFactory.result(page, respList);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void appSetTop(SysAppReq req) {
        SysAppEntity currentApp = this.getBaseMapper().selectById(req.getAppId());

        // 如果应用下没有菜单，不能激活
        boolean hasMenu = sysMenuService.hasMenu(currentApp.getAppCode());
        if (!hasMenu) {
            throw new ServiceException(ErrorEnum.ACTIVE_ERROR);
        }

        // 所有已激活的改为未激活
        LambdaUpdateWrapper<SysAppEntity> sysAppLambdaUpdateWrapper = new LambdaUpdateWrapper<>();
        sysAppLambdaUpdateWrapper.set(SysAppEntity::getTopFlag, YesOrNotEnum.N.getCode());
        sysAppLambdaUpdateWrapper.eq(SysAppEntity::getTopFlag, YesOrNotEnum.Y.getCode());
        this.update(sysAppLambdaUpdateWrapper);

        // 当前的设置为已激活
        currentApp.setTopFlag(YesOrNotEnum.Y.getCode());
        this.updateById(currentApp);
    }

    @Override
    public List<SysAppResp> getUserTopAppList() {

        // 获取用户拥有的appCode列表
//        List<String> userAppCodeList = sysMenuService.getUserAppCodeList();
//        if (CollUtil.isEmpty(userAppCodeList)){
//            return Collections.emptyList();
//        }
//        // 根据appCode获取对应的app详情
        LambdaQueryWrapper<SysAppEntity> wrapper = this.createWrapper(null);
//        wrapper.in(SysAppEntity::getAppCode, userAppCodeList);

        // 仅查询code和name
        wrapper.select(SysAppEntity::getAppName, SysAppEntity::getAppCode);

        // 根据激活顺序排序
        wrapper.orderByDesc(SysAppEntity::getTopFlag);

        List<SysAppEntity> sysAppList = this.list(wrapper);
        return Convert.convert(new TypeReference<>() {
        }, sysAppList);
    }

//    @Override
//    public Set<SimpleDict> getAppsByAppCodes(Set<String> appCodes) {
//        HashSet<SimpleDict> simpleDicts = new HashSet<>();
//
//        LambdaQueryWrapper<SysAppEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.in(SysAppEntity::getAppCode, appCodes);
//        queryWrapper.select(SysAppEntity::getId, SysAppEntity::getAppCode, SysAppEntity::getAppName);
//
//        List<SysAppEntity> list = this.list(queryWrapper);
//        for (SysAppEntity sysAppEntity : list) {
//            SimpleDict simpleDict = new SimpleDict();
//            simpleDict.setId(sysAppEntity.getAppId());
//            simpleDict.setCode(sysAppEntity.getAppCode());
//            simpleDict.setName(sysAppEntity.getAppName());
//            simpleDicts.add(simpleDict);
//        }
//
//        return simpleDicts;
//    }

    @Override
    public String getAppNameByAppCode(String appCode) {
        String emptyName = "空应用";
        if (ObjectUtil.isEmpty(appCode)) {
            return emptyName;
        }

        LambdaQueryWrapper<SysAppEntity> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.select(SysAppEntity::getAppName)
                .eq(SysAppEntity::getAppCode, appCode);
        SysAppEntity sysApp = this.getOne(queryWrapper);

        return ObjectUtil.isEmpty(sysApp.getAppName()) ? emptyName : sysApp.getAppName();
    }
//
//    @Override
//    public String getActiveAppCode() {
//        LambdaQueryWrapper<SysAppEntity> queryWrapper = new LambdaQueryWrapper<>();
//        queryWrapper.select(SysAppEntity::getAppCode);
//        queryWrapper.eq(SysAppEntity::getTopFlag, YesOrNotEnum.Y.getCode());
//        queryWrapper.eq(SysAppEntity::getDelFlag, YesOrNotEnum.N.getCode());
//        List<SysAppEntity> list = this.list(queryWrapper);
//        if (list.isEmpty()) {
//            return null;
//        } else {
//            return list.get(0).getAppCode();
//        }
//    }

    @Override
    public SysAppDto getAppInfoByAppCode(String appCode) {
        if (StrUtil.isBlank(appCode)) {
            throw new BusException(ErrorEnum.ERROR_NULL_PARAMS);
        }
        LambdaQueryWrapper<SysAppEntity> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.eq(SysAppEntity::getAppCode, appCode);
        SysAppEntity sysAppEntity = this.getOne(lambdaQueryWrapper, false);
        if (ObjectUtil.isNotEmpty(sysAppEntity)) {
            return Convert.convert(new TypeReference<>() {}, sysAppEntity);
        } else {
            return new SysAppDto();
        }
    }

    @Override
    public List<SysAppDto> getSortedApps() {
        LambdaQueryWrapper<SysAppEntity> wrapper = this.createWrapper(null);
        wrapper.select(SysAppEntity::getAppName, SysAppEntity::getAppCode)
                .eq(SysAppEntity::getStatusFlag, StatusEnum.ENABLE.getCode());
        List<SysAppEntity> sysApplist = this.list(wrapper);
        return Convert.convert(new TypeReference<>() {
        }, sysApplist);
    }
//
//    /**
//     * 获取系统应用
//     *
//     * @author GD
//     * @since 2020/3/26 9:56
//     */
//    private SysAppEntity querySysApp(SysAppVo sysAppVo) {
//        SysAppEntity sysApp = this.getById(sysAppVo.getId());
//        if (ObjectUtil.isNull(sysApp)) {
//            throw new ServiceException(ErrorEnum.APP_NOT_EXIST);
//        }
//        return sysApp;
//    }

    /**
     * 创建wrapper
     *
     * @author GD
     * @since 2020/11/6 10:16
     */
    private LambdaQueryWrapper<SysAppEntity> createWrapper(SysAppReq req) {
        LambdaQueryWrapper<SysAppEntity> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysAppEntity::getDelFlag, YesOrNotEnum.N.getCode());

        if (ObjectUtil.isEmpty(req)) {
            return wrapper;
        }
        wrapper.eq(ObjectUtil.isNotEmpty(req.getAppId()), SysAppEntity::getAppId, req.getAppId())
                .like(ObjectUtil.isNotEmpty(req.getAppName()), SysAppEntity::getAppName, req.getAppName())
                .like(ObjectUtil.isNotEmpty(req.getAppCode()), SysAppEntity::getAppCode, req.getAppCode())
                .eq(ObjectUtil.isNotEmpty(req.getTopFlag()), SysAppEntity::getTopFlag, req.getTopFlag())
                .eq(ObjectUtil.isNotEmpty(req.getStatusFlag()), SysAppEntity::getStatusFlag, req.getStatusFlag())
                .orderByAsc(SysAppEntity::getAppSort);
        return wrapper;
    }

}
